/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import type {TurboModule} from 'react-native/Libraries/TurboModule/RCTExport';
import {TurboModuleRegistry} from 'react-native';

/**
 * 音频选择参数
 */
export interface SelectAudioOptions {
  /**
   * 最大可以选择的数量.范围1-500.
   */
  maxSelectNumber?: number;
}

/**
 * 音频选择结果
 */
export type SelectAudioResult = Array<string>;

/**
 * 媒体类型。
 */
export type SelectCameraMediaTypes = Array<'photo' | 'video'>;

/**
 * 相机的位置
 */
export enum SelectCameraPosition {
  /**
   * 相对于设备屏幕没有固定的朝向的相机。
   */
  CAMERA_POSITION_UNSPECIFIED = 0,
  /**
   * 后置相机。
   */
  CAMERA_POSITION_BACK = 1,
  /**
   * 前置相机。
   */
  CAMERA_POSITION_FRONT = 2,
  /**
   * 折叠态相机。
   * 从API version 11开始支持，从API version 12开始废弃。。
   */
  CAMERA_POSITION_FOLD_INNER = 3,
}

/**
 * 相机选择参数
 */
export interface SelectCameraOptions {
  /**
   * 相机位置。
   */
  cameraPosition: SelectCameraPosition;
  /**
   * 保存配置信息的uri
   */
  saveUri?: string;
  /**
   * 录制的最大时长（单位：秒）。默认为0，不设置最大录制时长。
   */
  videoDuration?: number;
}

/**
 * 相机选择结果
 */
export interface SelectCameraResult {
  /**
   * 保存配置信息的uri
   */
  resultCode: number;
  /**
   * 返回的uri地址。若saveUri为空，resultUri为公共媒体路径。若saveUri不为空且具备写权限，resultUri与saveUri相同。若saveUri不为空且不具备写权限，则无法获取到resultUri。
   */
  resultUri: string;
  /**
   * 返回的媒体类型。
   */
  mediaType: string;
}

/**
 * 枚举，过滤条件。
 */
export enum SelectContactFilterCondition {
  IS_NOT_NULL,
  EQUAL_TO,
  NOT_EQUAL_TO,
  IN,
  NOT_IN,
  CONTAINS,
}

/**
 * 过滤值。
 */
export type SelectContactValueType = number | string | boolean;

/**
 * 联系人过滤参数。
 */
export interface SelectContactFilterOptions {
  /**
   * 过滤条件。
   */
  filterCondition: SelectContactFilterCondition;
  /**
   * 过滤值，默认为undefined。
   */
  value?: string | SelectContactValueType[];
}

/**
 * 枚举，联系人数据字段。
 */
enum SelectContactDataField {
  EMAIL,
  PHONE,
  ORGANIZATION,
}

/**
 * 联系人数据过滤项。
 */
export interface SelectContactDataFilter {
  field: SelectContactDataField;
  options: Array<SelectContactFilterOptions>;
}

/**
 * 联系人过滤条件。
 */
export interface SelectContactFilterClause {
  /**
   * 联系人id。
   */
  id?: Array<SelectContactFilterOptions>;
  /**
   * 联系人姓名。
   */
  name?: Array<SelectContactFilterOptions>;
  /**
   * 联系人数据过滤项。
   */
  dataItem?: SelectContactDataFilter;
  /**
   * 专注模式。
   */
  focusModeList?: Array<SelectContactFilterOptions>;
}

/**
 * 枚举，联系人过滤类型。
 */
export enum SelectContactFilterType {
  SHOW_FILTER,
  DEFAULT_SELECT,
  SHOW_FILTER_AND_DEFAULT_SELECT,
}

/**
 * 联系人查询过滤器。
 */
export interface SelectContactFilter {
  /**
   * 	过滤条件。
   */
  filterClause: SelectContactFilterClause;
  /**
   * 	过滤类型。
   */
  filterType: SelectContactFilterType;
}

/**
 * 选择联系人参数。
 */
export interface SelectContactOptions {
  /**
   * 是否为多选，true:多选，false:单选。默认值为false。
   */
  isMultiSelect?: boolean;
  /**
   * 联系人选择数量上限。默认值为10000。
   */
  maxSelectable?: number;
  /**
   * 是否按联系人姓名维度展示，true:按联系人姓名维度展示，false:按联系人号码维度展示。默认值为false。
   */
  isDisplayedByName?: boolean;
  /**
   * 联系人查询过滤器。
   */
  filter?: SelectContactFilter;
}

export interface Email {
  email: string;
  displayName?: string;
  labelName?: string;
  labelId?: number;
}

export interface Group {
  groupId?: number;
  title: string;
}

export interface Event {
  eventDate: string;
  labelName?: string;
  labelId?: number;
}

export interface ImAddress {
  imAddress: string;
  labelName?: string;
  labelId?: number;
}

export interface PhoneNumber {
  phoneNumber: string;
  labelName?: string;
  labelId?: number;
}

export interface Portrait {
  uri: string;
}
export interface PostalAddress {
  city?: string;
  country?: string;
  labelName?: string;
  neighborhood?: string;
  pobox?: string;
  postalAddress: string;
  postcode?: string;
  region?: string;
  street?: string;
  labelId?: number;
}

export interface Relation {
  relationName: string;
  labelName?: string;
  labelId?: number;
}

export interface SipAddress {
  sipAddress: string;
  labelName?: string;
  labelId?: number;
}

export interface Website {
  website: string;
}

export interface Name {
  familyName?: string;
  familyNamePhonetic?: string;
  fullName: string;
  givenName?: string;
  givenNamePhonetic?: string;
  middleName?: string;
  middleNamePhonetic?: string;
  namePrefix?: string;
  nameSuffix?: string;
}

export interface NickName {
  nickName: string;
}

export interface Note {
  noteContent: string;
}

export interface Organization {
  name: string;
  title?: string;
}

/**
 * 联系人对象类。
 */
export interface Contact {
  /**
   * 联系人的id，由系统自动生成。
   */
  id?: number;
  /**
   * 联系人的key，由系统自动生成。
   */
  key?: string;
  emails?: Email[];
  /**
   * 联系人的生日、周年纪念等重要日期列表。
   */
  events?: Event[];
  /**
   * 联系人的群组列表。
   */
  groups?: Group[];
  /**
   * 联系人的即时消息地址列表。
   */
  imAddresses?: ImAddress[];
  phoneNumbers?: PhoneNumber[];
  /**
   * 联系人的头像。
   */
  portrait?: Portrait;
  /**
   * 联系人的邮政地址列表。
   */
  postalAddresses?: PostalAddress[];
  /**
   * 联系人的关系列表。
   */
  relations?: Relation[];
  /**
   * 联系人的会话发起协议(SIP)地址列表。
   */
  sipAddresses?: SipAddress[];
  websites?: Website[];
  name?: Name;
  nickName?: NickName;
  /**
   * 联系人的备注。
   */
  note?: Note;
  /**
   * 联系人的组织信息。
   */
  organization?: Organization;
}

/**
 * 选择联系人结果。
 */
export type SelectContactResult = Array<Contact>;

/**
 * 枚举，选择的文档类型。
 */
export enum DocumentSelectMode {
  FILE = 0,
  FOLDER = 1,
  MIXED = 2,
}

/**
 * 枚举，文件聚合类型。
 */
export enum MergeTypeMode {
  DEFAULT = 0,
  AUDIO = 1,
  VIDEO = 2,
  DOCUMENT = 3,
  PICTURE = 4,
}

/**
 * 文档选择选项。
 */
export interface SelectDocumentOptions {
  /**
   * 指定选择的文件或者目录的URI。默认为空（效果为拉起最近打开页）。
   */
  defaultFilePathUri?: string;
  /**
   * 选择文件的后缀类型。传入字符串数组，每一项代表一个后缀选项，每一项内部用"|"分为两部分，第一部分为描述，第二部分为过滤后缀。
   * 没有"|"则没有描述，该项整体是一个过滤后缀。每项过滤后缀可以存在多个后缀名，则每一个后缀名之间用英文逗号进行分隔，传入数组长度不能超过100，
   * 例如：['图片(.png, .jpg)|.png,.jpg', '文档|.txt', '视频|.mp4', '.pdf']。
   */
  fileSuffixFilters?: Array<string>;
  /**
   * 选择文件最大个数，上限为500个，有效值范围1-500（选择目录仅对具有该系统能力的设备开放。且目录选择的最大个数为1）。默认值是500。
   */
  maxSelectNumber?: number;
  /**
   * Picker选择的文档类型，默认值是FILE(文件类型)。
   */
  selectMode?: DocumentSelectMode;
  /**
   * 拉起授权Picker，默认为false（非授权模式）。当authMode为true时为授权模式，defaultFilePathUri必填，表明待授权URI。
   */
  authMode?: boolean;
  /**
   * 支持批量授权模式，默认为false（非批量授权模式）。当multiAuthMode为true时为批量授权模式。当multiAuthMode为true时，只有multiUriArray参数生效，其他参数不生效。
   */
  multiAuthMode?: boolean;
  /**
   * 传入需要批量授权的URI数组（仅支持文件，文件夹不生效）。配合multiAuthMode使用。当multiAuthMode为false时，配置该参数不生效。默认为空（效果为拉起批量授权页面后展示的文件为空）。
   */
  multiUriArray?: Array<string>;
  /**
   * 开启聚合视图模式，支持拉起文件管理应用的聚合视图。默认为DEFAULT，表示该参数不生效，非聚合视图。当该参数置为非DEFAULT时，其他参数不生效。
   */
  mergeMode?: MergeTypeMode;
  /**
   * 是否支持加密（仅支持文件，文件夹不生效），默认为false。该参数为true时，在Picker界面可以选择对文件进行加密。
   */
  isEncryptionSupported?: boolean;
}

/**
 * 文档选择结果。
 */
export type SelectDocumentResult = Array<string>;

/**
 * 经纬度对象。
 */
export interface LatLng {
  longitude: number;
  latitude: number;
}

/**
 * 查询地点详情的参数。
 */
export interface QueryLocationOptions {
  /**
   * 地点详情页的地点ID。
   */
  siteId?: string;
  /**
   * 语言，请参见地图Picker支持语言，如果未设置，默认使用系统语言。
   */
  language?: string;
  /**
   * 地图中心点坐标。如果没有siteId，使用location查询地点详情。
   */
  location?: LatLng;
  /**
   * 地点的名称。如果没有siteId，使用name作为location的名称标注。
   */
  name?: string;
  /**
   * 地点的地址。如果没有siteId，使用address作为location的地址标注。
   */
  address?: string;
  /**
   * 是否显示商业信息（如打车），默认值为true。
   */
  showBusiness?: boolean;
}

/**
 * 地点选取的参数。
 */
export interface ChooseLocationOptions {
  /**
   * 地图中心点坐标。如果参数未传，使用设备当前位置作为中心点；如果未获取到设备当前位置，默认以故宫博物院为中心点。
   */
  location?: LatLng;
  /**
   * 语言，请参见地图Picker支持语言，如果未设置，默认使用系统语言。
   */
  language?: string;
  /**
   * 指定需要展示的POI类别。取值范围参见HwLocationType。
   */
  poiTypes?: Array<string>;
  /**
   * 是否展示搜索控件，默认值为false，异常值按默认值处理。
   */
  searchEnabled?: boolean;
  /**
   * 是否展示附近POI，默认值为false，异常值按默认值处理。
   */
  showNearbyPoi?: boolean;
}

export interface StreetNumber {
  direction?: string;
  distance?: number;
  location?: LatLng;
  streetNumber?: string;
  streetName?: string;
  formatAddress?: string;
}

export interface City {
  cityCode?: string;
  cityId?: string;
  cityName?: string;
}

/**
 * 地址详细信息。
 */
export interface AddressComponent {
  /**
   * 国家名。
   */
  countryName?: string;
  /**
   * 国家/地区码。
   */
  countryCode?: string;
  /**
   * 一级行政区。
   */
  adminLevel1?: string;
  adminLevel2?: string;
  adminLevel3?: string;
  adminLevel4?: string;
  adminLevel5?: string;
  /**
   * 地区、区域。
   */
  locality?: string;
  /**
   * 一级子区域。
   */
  subLocality1?: string;
  subLocality2?: string;
  /**
   * 街区、城区。
   */
  neighborhoods?: Array<string>;
  /**
   * 行政区划码。
   */
  adminCode?: string;
  postalCode?: string;
  city?: City;
  streetNumber?: StreetNumber;
}

/**
 * 地点选取结果
 */
export interface ChooseLocationResult {
  /**
   * 选点的地点ID。如果选点非POI，则不返回。
   */
  siteId?: string;
  location?: LatLng;
  /**
   * 选点的POI名称。如果选点非POI，则返回的name值为"标记点"。
   */
  name?: string;
  address: string;
  /**
   * 地址详细信息。
   */
  addressComponent?: AddressComponent;
  zoom: number;
}

/**
 * 区划选择页面初始选项。
 */
export interface SelectDistrictOptions {
  /**
   * 查询指定国家或地区的行政区划，国家或地区码必须符合ISO 3166-1 alpha-2规则。
   */
  countryCode?: string;
  language?: string;
  address?: string;
}

export interface District {
  siteId?: string;
  name?: string;
  location?: LatLng;
  adminLevel?: string;
  adminCode?: string;
  cityCode?: string;
  countryCode?: string;
}

/**
 * 区划选择请求的结果。
 */
export interface SelectDistrictResult {
  /**
   * 所选行政区划的级别信息。
   */
  districts: Array<District>;
  /**
   * 返回所选行政区划的地址信息。
   */
  addressDescription?: string;
}

/**
 * 枚举，可选择的媒体文件类型。
 **/
export enum PhotoViewMIMETypes {
  IMAGE_TYPE = 'image/*',
  VIDEO_TYPE = 'video/*',
  IMAGE_VIDEO_TYPE = '*/*',
  MOVING_PHOTO_IMAGE_TYPE = 'image/movingPhoto',
}

export enum CompleteButtonText {
  TEXT_DONE = 0,
  TEXT_SEND = 1,
  TEXT_ADD = 2,
}

/**
 * 文件类型的过滤配置。
 */
export interface MimeTypeFilter {
  /**
   * PhotoPicker可供用户选择媒体文件的过滤类型。 例如：“image/jpeg”、“video/mp4”等。
   */
  mimeTypeArray: Array<string>;
}

/**
 * 图库选择选项
 */
export interface SelectPhotoOptions {
  /**
   * 可选择的媒体文件类型，若无此参数，则默认为图片和视频类型。
   */
  MIMEType?: PhotoViewMIMETypes;
  /**
   * 选择媒体文件数量的最大值（最大可设置的值为500，若不设置则默认为50）。
   */
  maxSelectNumber?: number;
  /**
   * 是否支持搜索，true表示支持，false表示不支持，默认为true。
   */
  isSearchSupported?: boolean;
  /**
   * 是否支持拍照，true表示支持，false表示不支持，默认为true。
   */
  isPhotoTakingSupported?: boolean;
  /**
   * 是否支持编辑照片，true表示支持，false表示不支持，默认为true。
   */
  isEditSupported?: boolean;
  /**
   * 是否显示选择原图按钮，true表示显示，false表示不显示，默认为true。
   */
  isOriginalSupported?: boolean;
  /**
   * 文件类型的过滤配置，支持指定多个类型过滤。
   */
  mimeTypeFilter?: MimeTypeFilter;
  /**
   * 完成按钮显示的内容。完成按钮指在界面右下方，用户点击表示图片选择已完成的按钮。
   */
  completeButtonText?: CompleteButtonText;
}

/**
 * 图库选择返回结果
 */
export interface SelectPhotoResult {
  /**
   * 	返回图库选择后的媒体文件的uri数组，此uri数组只能通过临时授权的方式调用photoAccessHelper.getAssets接口去使用，具体使用方式参见用户文件uri介绍中的媒体文件uri的使用方式。
   */
  photoUris: Array<string>;
  /**
   * 是否是原图
   */
  isOriginalPhoto: boolean;
}

/**
 * 枚举，码类型。
 */
export enum ScanType {
  /**
   * 未知类型，用于事先不知道要扫哪种类型码的场景，此参数不可用作码图生成
   */
  FORMAT_UNKNOWN = 0,
  AZTEC_CODE = 1,
  CODABAR_CODE = 2,
  CODE39_CODE = 3,
  CODE93_CODE = 4,
  CODE128_CODE = 5,
  DATAMATRIX_CODE = 6,
  EAN8_CODE = 7,
  EAN13_CODE = 8,
  ITF14_CODE = 9,
  PDF417_CODE = 10,
  QR_CODE = 11,
  UPC_A_CODE = 12,
  UPC_E_CODE = 13,
  MULTIFUNCTIONAL_CODE = 14,
  /**
   * 条形码，包含：CODABAR、CODE 39、CODE 93、CODE 128、EAN-8、EAN-13、ITF-14、UPC-A、UPC-E，此参数不可用作码图生成
   */
  ONE_D_CODE = 100,
  /**
   * 二维码，包含：AZTEC、DATA MATRIX、PDF417、QR CODE、MULTIFUNCTIONAL CODE，此参数不可用作码图生成
   */
  TWO_D_CODE = 101,
  /**
   * 以上所有类型，此参数不可用作码图生成
   */
  ALL = 1001,
}

/**
 * 扫码参数。
 */
export interface StartScanOptions {
  /**
   * 设置扫码类型，默认扫码ALL（全部码类型）。
   */
  scanTypes?: Array<ScanType>;
  /**
   * 是否开启多码识别，默认false。
   */
  enableMultiMode?: boolean;
  /**
   * 是否开启相册，默认true。
   */
  enableAlbum?: boolean;
}

export interface ScanCodeRect {
  left: number;
  top: number;
  right: number;
  bottom: number;
}

export interface Point {
  x: number;
  y: number;
}

/**
 * 扫码结果。
 */
export interface StartScanResult {
  scanType: ScanType;
  /**
   * 码识别内容结果。
   */
  originalValue: string;
  /**
   * 码识别位置信息。
   */
  scanCodeRect?: ScanCodeRect;
  /**
   * 码识别角点位置信息，返回QR Code四个角点。
   */
  cornerPoints?: Array<Point>;
}

export interface Spec extends TurboModule {
  /**
   * 通过选择模式拉起audioPicker界面，用户可以选择一个或多个音频文件。接口采用Promise异步返回形式，传入可选参数AudioSelectOptions对象，返回选择音频文件的URI数组。
   * @param options
   */
  selectAudio(
    options: SelectAudioOptions
  ): Promise<SelectAudioResult | undefined>;

  /**
   * 拉起相机选择器，根据媒体类型进入相应的模式。使用Promise异步回调。
   * @param mediaTypes
   * @param options
   */
  selectCamera(
    mediaTypes: SelectCameraMediaTypes,
    options: SelectCameraOptions
  ): Promise<SelectCameraResult | undefined>;

  /**
   * 调用选择联系人接口，打开选择联系人UI界面，使用Promise异步回调。
   * @param options
   */
  selectContact(
    options: SelectContactOptions
  ): Promise<SelectContactResult | undefined>;

  /**
   * 通过选择模式拉起documentPicker界面，用户可以选择一个或多个文件。采用Promise异步返回形式。
   * @param options
   */
  selectDocument(
    options: SelectDocumentOptions
  ): Promise<SelectDocumentResult | undefined>;

  /**
   * 根据提供的参数拉起地点详情展示控件。使用Promise异步回调。
   * @param options
   */
  queryLocation(options: QueryLocationOptions): Promise<void>;

  /**
   * 根据提供的参数拉起地点选取控件。使用Promise异步回调。
   * @param options
   */
  chooseLocation(
    options: ChooseLocationOptions
  ): Promise<ChooseLocationResult | undefined>;

  /**
   * 根据提供的参数调出区划选择页面。使用Promise异步回调。
   * @param options
   */
  selectDistrict(
    options: SelectDistrictOptions
  ): Promise<SelectDistrictResult | undefined>;

  /**
   * 通过选择模式拉起photoPicker界面，用户可以选择一个或多个图片/视频。接口采用Promise异步返回形式
   * @param options
   */
  selectPhoto(
    options: SelectPhotoOptions
  ): Promise<SelectPhotoResult | undefined>;

  /**
   * 通过配置参数调用默认界面扫码，使用Promise异步回调返回扫码结果。
   * @param options
   */
  startScan(options: StartScanOptions): Promise<StartScanResult | undefined>;
}

export default TurboModuleRegistry.getEnforcing<Spec>('PickerModule') as Spec;
